import 'dart:async';
import 'dart:convert' as convert;
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; // 确保导入Provider
import 'package:shared_preferences/shared_preferences.dart';
import 'package:happy_elf_app/store/config.dart';
import 'package:happy_elf_app/utils/globalKey.dart';
import 'package:happy_elf_app/widgets/Loading/index.dart';
import 'package:happy_elf_app/widgets/Toast/index.dart';
import 'package:happy_elf_app/store/common.dart';

class Request {
  static Dio dio = Dio();
  CancelToken cancelToken = CancelToken();
  int timeout;

  Request({this.timeout = 100000}) {
    // 初始化时不获取Provider，只设置基础配置
    dio.options.connectTimeout = timeout;
    dio.options.receiveTimeout = timeout;

    // 拦截器配置（关键：在拦截器中延迟获取Provider）
    dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) async {
        // 1. 在请求时才获取Common Provider（此时上下文已初始化）
        final common = Provider.of<Common>(
          Global.navigatorKey.currentContext!,
          listen: false,
        );
        // 设置基础地址
        options.baseUrl = common.env['api'];
        // 设置Cookie
        // options.headers['Cookie'] = await getCookie();
        options.headers['Authorization'] = await getCookie();
        print('await getCookie()${await getCookie()}');
        return handler.next(options);
      },
      onResponse: (response, handler) {
        if (response.headers['set-cookie'] != null) {
          dio.options.headers['Cookie'] = response.headers['set-cookie']![0];
          setCookie(response.headers['set-cookie']![0]);
        }
        return handler.next(response);
      },
      onError: (DioError e, handler) {
        return handler.next(e);
      },
    ));
  }

  bool jumped = true;

  http({
    bool baseUrl = true,
    required String method,
    required String api,
    CancelToken? cancelToken,
    bool needToastErr = false,
    bool showLoad = false,
    String loadTxt = '请求中...',
    data,
    progress,
    error,
    String? mockHost,
  }) async {
    debugPrint("请求参数$data");
    DialogRoute? loadRoute;
    if (showLoad) {
      loadRoute = await showLoadingByRoute(noticeText: loadTxt);
    }
    if (!baseUrl) dio.options.baseUrl = '';
    dio.options.baseUrl = mockHost ?? dio.options.baseUrl;

    if (method == 'FORMDATA') {
      debugPrint("formdata请求参数$data");
      data = FormData.fromMap(data);
      method = 'POST';
    }

    try {
      var result = await dio.request(
        api,
        queryParameters: method == 'GET' ? data : null,
        data: method == 'GET' ? null : data,
        options: Options(method: method),
        cancelToken: cancelToken,
        onSendProgress: (int pro, int total) {
          if (progress != null) progress(pro, total);
        },
      );
      print('result$result');
      if (showLoad && loadRoute != null && loadRoute.isActive) {
        Navigator.of(Global.navigatorKey.currentContext!)
            .removeRoute(loadRoute);
      }

      if (result.data.runtimeType == String) {
        Toast.show(
          context: Global.navigatorKey.currentContext!,
          message: '请求失败，请联系管理员',
        );
        result.data = {
          'success': false,
          'code': 1001,
          'data': null,
          'message': "请求失败，请联系管理员"
        };
      }

      if (result.data['code'] != 601 &&
          result.data['code'] != 200 &&
          needToastErr) {
        Toast.show(
          context: Global.navigatorKey.currentContext!,
          message: result.data['message'],
        );
      }

      // 2. 需要时再获取UserData Provider（延迟到实际使用时）
      if (result.data['code'] == 601 && jumped) {
        Toast.show(
          context: Global.navigatorKey.currentContext!,
          message: '登录过期，请重新登录',
        );
        dio.options.headers['Cookie'] = '';
        SharedPreferences prefs = await SharedPreferences.getInstance();
        prefs.remove('userData');

        if (jumped) {
          jumped = false;
          Future.delayed(const Duration(seconds: 1), () {
            jumped = true;
            Navigator.of(Global.navigatorKey.currentContext!)
                // ignore: unnecessary_null_comparison
                .pushNamedAndRemoveUntil("Login", (route) => route == null);
          });
        }
      }
      // if (result.data['code'] != 200) {
      //   Toast.show(
      //       context: Global.navigatorKey.currentContext!,
      //       message: result.data['message']);
      // }

      if (api == '/app/login' && result.data['data']['token'] != null) {
        print('result.data[====${result.data['data']['token']}');
        dio.options.headers['Cookie'] = result.data['data']['token'];
        setCookie(result.data['data']['token']);
      }

      return result.data;
    } on DioError catch (e) {
      if (showLoad) {
        hideLoading();
      }
      print('eeeee---$e');
      if (e.toString().indexOf('Connecting timed out') != -1) {
        Toast.show(
          context: Global.navigatorKey.currentContext!,
          message: '请求连接超时',
        );
      } else if (!e.toString().contains('cancelled')) {
        Toast.show(
          context: Global.navigatorKey.currentContext!,
          message: '请检查网络连接！',
        );
      }
    }
    return null;
  }

  setCookie(data) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString('cookie', convert.jsonEncode(data));
  }

  getCookie() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String? cookie = prefs.getString('cookie') != null
        ? convert.jsonDecode(prefs.getString('cookie')!)
        : '';
    return cookie;
  }
}
